package com.dctp.common.utils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.NumberFormat;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 数字处理工具类
 */
public class NumberUtil {

    // ---------------------- 基础转换 ----------------------

    /**
     * 字符串转整数（失败返回默认值）
     * @param str          输入字符串
     * @param defaultValue 转换失败时的默认值
     */
    public static int parseInt(String str, int defaultValue) {
        if (str == null || str.isEmpty()) return defaultValue;
        try {
            return Integer.parseInt(str.trim());
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }


    public static BigDecimal parseBigDecimal(String str) {
        if (str == null || str.isEmpty()) return BigDecimal.ZERO;
        try {
            return new BigDecimal(str.trim());
        }catch (NumberFormatException e) {
            return BigDecimal.ZERO;
        }
    }

    /**
     * 字符串转长整数（失败返回默认值）
     */
    public static long parseLong(String str, long defaultValue) {
        if (str == null || str.isEmpty()) return defaultValue;
        try {
            return Long.parseLong(str.trim());
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    /**
     * 字符串转浮点数（失败返回默认值）
     */
    public static double parseDouble(String str, double defaultValue) {
        if (str == null || str.isEmpty()) return defaultValue;
        try {
            return Double.parseDouble(str.trim());
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    // ---------------------- 格式化 ----------------------

    /**
     * 添加千分位分隔符（示例：1234567 → "1,234,567"）
     */
    public static String formatWithCommas(Number number) {
        return NumberFormat.getInstance().format(number);
    }

    /**
     * 格式化为指定位数的小数（四舍五入）
     * @param value   原始数值
     * @param places  保留小数位数
     */
    public static double round(double value, int places) {
        if (places < 0) throw new IllegalArgumentException("小数位数不能为负数");
        BigDecimal bd = BigDecimal.valueOf(value);
        return bd.setScale(places, RoundingMode.HALF_UP).doubleValue();
    }

    // ---------------------- 数学运算 ----------------------

    /**
     * 计算百分比（示例：calculatePercentage(25, 100) → 25.0）
     */
    public static double calculatePercentage(double part, double whole) {
        if (whole == 0) return 0;
        return (part / whole) * 100;
    }

    /**
     * 精确加法运算（避免浮点精度丢失）
     */
    public static double add(double d1, double d2) {
        return BigDecimal.valueOf(d1).add(BigDecimal.valueOf(d2)).doubleValue();
    }

    // ---------------------- 范围约束 ----------------------

    /**
     * 将数值限制在[min, max]范围内
     */
    public static int clamp(int value, int min, int max) {
        return Math.max(min, Math.min(max, value));
    }

    /**
     * 判断数值是否在区间内（包含边界）
     */
    public static boolean isInRange(double value, double min, double max) {
        return value >= min && value <= max;
    }

    // ---------------------- 随机数生成 ----------------------

    /**
     * 生成指定范围的随机整数 [min, max]
     */
    public static int randomInt(int min, int max) {
        return ThreadLocalRandom.current().nextInt(min, max + 1);
    }

    /**
     * 生成指定范围的随机浮点数 [min, max)
     */
    public static double randomDouble(double min, double max) {
        return ThreadLocalRandom.current().nextDouble(min, max);
    }

    // ---------------------- 其他工具 ----------------------

    /**
     * 判断字符串是否为有效数字（整数或浮点数）
     */
    public static boolean isNumeric(String str) {
        if (str == null || str.isEmpty()) return false;
        return str.matches("-?\\d+(\\.\\d+)?");
    }

    /**
     * 将整数转为十六进制字符串（小写）
     */
    public static String toHex(int num) {
        return Integer.toHexString(num);
    }

    /**
     * 十六进制字符串转整数
     */
    public static int fromHex(String hex) {
        return Integer.parseInt(hex, 16);
    }


    /**
     * 生成8位随机数字（范围：10000000 ~ 99999999）
     * 适用于短信验证码、订单号等场景
     */
    public static int random8Digits() {
        // 生成范围 [10000000, 99999999]
        return ThreadLocalRandom.current().nextInt(10_000_000, 100_000_000);
    }

    public static int random6Digits() {
        // 生成范围 [100000, 999999]
        return ThreadLocalRandom.current().nextInt(10_000_0, 100_000_0);
    }

    public static BigDecimal fixedOrRatio(BigDecimal fixed, BigDecimal base, BigDecimal ratio) {
        return (fixed != null && fixed.compareTo(BigDecimal.ZERO) > 0)
                ? fixed : base.multiply(ratio);
    }

    public static boolean isValidDecimal(Object v) {
        try {
            if (v == null) return true;
            new java.math.BigDecimal(v.toString());
            return true;
        } catch (Exception e) {
            return false;
        }
    }

}